package com.wxsong.authplatform.authweb.shiro.config;

import com.wxsong.authplatform.authweb.shiro.authen.AuthRealm;
import org.apache.shiro.authc.credential.DefaultPasswordService;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.DefaultHashService;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.SimpleByteSource;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login/to_login"); //  登录页面
        shiroFilterFactoryBean.setSuccessUrl("/main/index");//登录成功后的页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");  //未授权的页面
        ////自定义过滤器
        Map<String,String> filterChainDefinitionMap=new LinkedHashMap<>();
        filterChainDefinitionMap.put("/static/**", "anon");  //不会被拦截的地址
        filterChainDefinitionMap.put("/js/**", "anon");  //不会被拦截的地址
        filterChainDefinitionMap.put("/css/**", "anon");  //不会被拦截的地址
        filterChainDefinitionMap.put("/imgs/**", "anon");  //不会被拦截的地址
        filterChainDefinitionMap.put("/common/**", "anon");  //不会被拦截的地址
        filterChainDefinitionMap.put("/favicon.ico", "anon");  //不会被拦截的地址
        filterChainDefinitionMap.put("/login/*", "anon");  //不会被拦截的地址
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/*", "authc");    //表示需要认证才可以访问
        filterChainDefinitionMap.put("/**", "authc");   //表示需要认证才可以访问
        filterChainDefinitionMap.put("/*.*", "authc");  //表示需要认证才可以访问
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager(){
        DefaultSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(authRealm());
        return securityManager;
    }

    @Bean
    public AuthRealm authRealm(){
        AuthRealm authRealm = new AuthRealm();
        authRealm.setCredentialsMatcher(passwordMatcher());
        return authRealm;
    }

    @Bean
    public PasswordMatcher passwordMatcher(){
        String salt = "";
        DefaultPasswordService passwordService = new DefaultPasswordService();
        DefaultHashService hashService = new DefaultHashService();
        hashService.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
        hashService.setPrivateSalt(new SimpleByteSource(salt));         //私盐
        hashService.setGeneratePublicSalt(true);                        //是否生成公盐
        hashService.setRandomNumberGenerator(new SecureRandomNumberGenerator());    //用于生成公盐
        hashService.setHashIterations(2);
        passwordService.setHashService(hashService);

        PasswordMatcher passwordMatcher = new PasswordMatcher();
        passwordMatcher.setPasswordService(passwordService);
        return passwordMatcher;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) {
        AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(manager);
        return advisor;
    }

}
